﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using ProjectRoughWork.Engine.SoundManager;
using SkinnedModel;
using ProjectRoughWork;

namespace ProjectRoughWork
{
    class Soldier : SquadActor
    {
        public Soldier(string modelType)
            : base()
        {
            //Initialize soldier parameters


            unitType = "Soldier";
            gunRange = 400f;
            gunFireRate = 1000f;

            maxHealth = 2000f;
            currentHealth = maxHealth;
            
            //Assign the model name to be loaded
            modelName = modelType;



            InitVertices();

            collisionRadius = size;

            //Setting up origin and bounding sphere

            mOrigin = new Vector3(mPos.X + size / 2, mPos.Y + size / 2, mPos.Z + size / 2);
            bSphere = new BoundingSphere(mOrigin, size);

            mRotation = 0;
            mOffsetRotation = -90;
        }

        //Sets up stuff for placeholder model

        public void InitVertices()
        {


            size = 20;            
            //Initialize the model
           // if (modelName != null)
                //Store previous device state and content state
                GraphicsDevice oldDevice = Game1.GetGraphicsDevice();
                ContentManager oldContent = Game1.GetContentManager();

               soldier = new SkinnedModel(oldContent.Load<Model>(modelName),
                   getPosition(), Vector3.Up * getRotation(), new Vector3(size / 10),
                   oldDevice,
                   oldContent);

               soldier.Player.StartClip("Run", TimeSpan.FromMilliseconds(0),
                                TimeSpan.FromMilliseconds(1), false);

               rifle = Game1.GetContentManager().Load<Model>("nerf deploy cs-6");

               handIndex = soldier.Model.Bones["R_Hand"].Index - 13;
               // transforms = new Matrix[soldier.Bones.Count];
               // soldier.CopyAbsoluteBoneTransformsTo(transforms);



            vertices = new VertexPositionColorTexture[8];

            vertices[0].Position = new Vector3(0, 0, 0);
            vertices[0].Color = Color.Red;

            vertices[1].Position = new Vector3(0, size, 0);
            vertices[1].Color = Color.Red;

            vertices[2].Position = new Vector3(size, size, 0);
            vertices[2].Color = Color.Red;

            vertices[3].Position = new Vector3(size, 0, 0);
            vertices[3].Color = Color.Red;

            vertices[4].Position = new Vector3(0, 0, size);
            vertices[4].Color = Color.Red;

            vertices[5].Position = new Vector3(0, size, size);
            vertices[5].Color = Color.Red;

            vertices[6].Position = new Vector3(size, size, size);
            vertices[6].Color = Color.Red;

            vertices[7].Position = new Vector3(size, 0, size);
            vertices[7].Color = Color.Red;

            short[] temp = {
                               0,1,2,       //Front
                               2,3,0,
                               4,5,1,       //Left
                               1,0,4,
                               4,5,6,       //Back
                               6,7,4,
                               3,2,6,       //Right
                               6,7,3,
                               0,4,7,       //Bottom
                               7,3,0,
                               1,5,6,       //Top
                               6,2,1
                           };

            indices = temp;
        }

        public override bool Shoot(Vector3 target)
        {
            

            if (canFire)
            {
                canFire = false;


                
                //Create rifle nerf and AI that'll manipulate it, use them to make appropriate events and queue them

                RifleNerf nerf = new RifleNerf(mPos, mID);
                RifleNerfAI nerfAI = new RifleNerfAI(nerf, target, (GameplayScreen)ScreenManager.GetInstance().getTop());   //Need to fix

                EventAddActor addEvt = new EventAddActor(nerf);
                EventAttachProcess attachEvt = new EventAttachProcess(nerfAI);

                EventManager.GetInstance().VQueueEvent(addEvt);
                EventManager.GetInstance().VQueueEvent(attachEvt);

                // Play the sound effect
                SoundManager.GetInstance().playSound(this.Position, SoundManager.FIRE_SOLDIER);
                Firing = true;

                return true;
            }

            Firing = false;
            return false; 
        }

        public override void VOnUpdate()
        {
            base.VOnUpdate();

            if (soldier.Player.Done)
            {
                if (Moving)
                {
                   soldier.Player.StartClip("Run", TimeSpan.FromMilliseconds(0),
                                 TimeSpan.FromMilliseconds(800), false);
                }
            

                if (Firing)
                {                     
                    soldier.Player.StartClip("Shoot", TimeSpan.FromMilliseconds(0),
                                         TimeSpan.FromMilliseconds(600), false);
                }

                if (isDead())
                    soldier.Player.StartClip("Idle", true);
            }
            soldier.Update(Game1.GetGameTime());

        }

        public override void VRender()
        {
           GraphicsDevice device = Game1.GetGraphicsDevice();

            Effect customEffect = Game1.GetCustomEffect();
            customEffect.Parameters["World"].SetValue(Matrix.CreateTranslation(mPos));

            //Remember old graphics device 
              BlendState tempBlend = Game1.GetGraphicsDevice().BlendState;
              DepthStencilState tempDepth = Game1.GetGraphicsDevice().DepthStencilState;
              RasterizerState tempRasterizer = Game1.GetGraphicsDevice().RasterizerState;
              SamplerState tempSample = Game1.GetGraphicsDevice().SamplerStates[0];
            
            //Calculate the starting world matrix for marine model
            Matrix baseWorld = Matrix.CreateScale(1.5f) *
                Matrix.CreateRotationY(mRotation + MathHelper.PiOver2) *
                /*
                Matrix.CreateRotationY(NormalizeRotation(90)) * 
                Matrix.CreateRotationY(NormalizeRotation(mRotation)) *          //Shakir Edit March 30th, 2011 - Fixed Rotation
                Matrix.CreateRotationY(NormalizeRotation(-90)) * */
                customEffect.Parameters["World"].GetValueMatrix();
 

          /*  foreach (ModelMesh mesh in soldier.Meshes)
            {
                Matrix localWorld = transforms[mesh.ParentBone.Index]
                    * baseWorld;
                foreach (ModelMeshPart part in mesh.MeshParts)
                {

                    BasicEffect e = (BasicEffect)part.Effect;
                */
                    //reset the graphics device to the default state to draw the solid model
                    //Without this model textures appear transparent
                    device.BlendState = BlendState.Opaque;
                    device.DepthStencilState = DepthStencilState.Default;
                    device.RasterizerState = RasterizerState.CullCounterClockwise;
                    device.SamplerStates[0] = SamplerState.LinearWrap;
            
                   soldier.Draw(customEffect.Parameters["View"].GetValueMatrix(),
                                customEffect.Parameters["Projection"].GetValueMatrix(),
                                baseWorld);

                   foreach (ModelMesh mesh in rifle.Meshes)
                   {
                       foreach (BasicEffect effect in mesh.Effects)
                       {

                           //Rifle 
                           Matrix rifleTransform = Matrix.CreateScale(1.8f) *
                                Matrix.CreateFromYawPitchRoll(MathHelper.PiOver2, -0.45f,
                                -MathHelper.PiOver2 - 0.3f) *
                                Matrix.CreateTranslation(new Vector3(0, 2.0f, -1.0f));

                           effect.World = rifleTransform *
                              soldier.Player.WorldTransforms[handIndex] * baseWorld;

                           effect.View = customEffect.Parameters["View"].GetValueMatrix();
                           effect.Projection = customEffect.Parameters["Projection"].GetValueMatrix();

                       }

                       mesh.Draw();
                   }
                   /* e.World = localWorld;
                    e.View = Game1.GetBasicEffect().View;
                    e.Projection = Game1.GetBasicEffect().Projection;
                    e.LightingEnabled = true;
                    e.EnableDefaultLighting();
                }

                mesh.Draw();
             }
            */ 
            //Call render for model
            base.VRender();

            //reset the graphics device to the previous state
            device.BlendState = tempBlend;
            device.DepthStencilState = tempDepth;
            device.RasterizerState = tempRasterizer;
            device.SamplerStates[0] = tempSample;
            
           /* foreach (EffectPass pass in customEffect.CurrentTechnique.Passes)
            {
                pass.Apply();
                device.DrawUserIndexedPrimitives<VertexPositionColorTexture>(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, indices.Length / 3);
            }*/

            base.VRender();


        }

        //Data Member

        VertexPositionColorTexture[] vertices;
        short[] indices;
        int size;

        // Data Members added
        // Model soldier; 
        // Matrix[] transforms;
        SkinnedModel soldier;
        Model rifle;
        int handIndex;
       
    }
}
